# Import the Markup class from Flask for creating safe HTML strings.
from flask import Markup
# Import the base Model class from Flask-AppBuilder.
from flask_appbuilder import Model
# Import column types and relationship-defining constructs from SQLAlchemy.
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Text
# Import the relationship function to define relationships between models.
from sqlalchemy.orm import relationship

# Import custom base models and mixins from the application.
from myapp.models.base import MyappModelBase
from myapp.models.helpers import AuditMixinNullable

# Get the metadata object from the base Flask-AppBuilder Model.
# This metadata is shared across all models and holds the schema information.
metadata = Model.metadata


# Define the Docker class, which maps to the 'docker' table in the database.
# This model represents a Docker image build configuration.
class Docker(Model, AuditMixinNullable, MyappModelBase):
    # Specify the table name in the database.
    __tablename__ = 'docker'
    # Define the primary key column.
    id = Column(Integer, primary_key=True)
    # Define the foreign key relationship to the 'project' table.
    project_id = Column(Integer, ForeignKey('project.id'), nullable=False)
    # Establish the ORM relationship to the Project model.
    project = relationship('Project', foreign_keys=[project_id])
    # A description of the Docker build.
    describe = Column(String(200), nullable=True)
    # The base image used for the build.
    base_image = Column(String(200), nullable=True)
    # The target image name and tag for the build result.
    target_image = Column(String(200), nullable=True, default='')
    # The name and tag of the last successfully built image.
    last_image = Column(String(200), nullable=True, default='')
    # A boolean flag indicating if the image requires GPU resources to run.
    need_gpu = Column(Boolean, nullable=True, default=False)
    # A boolean flag to enable or disable consecutive builds.
    consecutive_build = Column(Boolean, default=True)
    # A JSON string for storing extensible, miscellaneous data.
    expand = Column(Text(65536), default='{}')

    # Define the string representation of the Docker object.
    def __repr__(self):
        # When an instance is printed, it will show its label (assuming a 'label' attribute exists).
        return self.label

    # A read-only property that generates an HTML 'save' link for the list view.
    @property
    def save(self):
        # The Markup object ensures that the HTML is rendered as-is and not escaped.
        return Markup(f'<a href="/docker_modelview/save/{self.id}">保存</a>')

    # A read-only property that generates HTML links for 'debug', 'clear', and 'save' actions.
    @property
    def debug(self):
        # These links are intended to be displayed in the list view for quick actions.
        return Markup(
            f'<a target=_blank href="/docker_modelview/debug/{self.id}">调试</a> | <a '
            f' href="/docker_modelview/delete_pod/{self.id}">清理</a> | <a target=_blank'
            f' href="/docker_modelview/save/{self.id}">保存</a>'
        )

    # A read-only property that generates an HTML snippet to display the image history.
    @property
    def image_history(self):
        # This provides a formatted summary of the base, last, and target images.
        return Markup(
            f'基础镜像:{self.base_image}<br>'
            f'当前镜像:{self.last_image if self.last_image else self.base_image}<br>'
            f'目标镜像:{self.target_image}'
        )
